package org.zjx.data.route.impl;

import com.alibaba.fastjson2.annotation.JSONType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.zjx.command.entity.Route;
import org.zjx.command.entity.screen.Address;
import org.zjx.command.enums.TeleportType;

/**
 * 跑路路由类
 * 表示同场景内移动的路径
 */

@JSONType(typeName = "RunningRoute")
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class RunningRoute extends AbstractRoute {
    private static final double OUTDOOR_SPEED = 3; // 室外速度(单位距离/秒)
    private static final double INDOOR_SPEED = 2; // 室内速度


    /**
     * 构造函数
     *
     * @param start  起点
     * @param end    终点
     * @throws IllegalArgumentException 如果不在同一场景
     */
    public RunningRoute(Address start, Address end) {
        super(start, end, calculateTime(start, end), TeleportType.RUNNING, false);
        if (!start.getCity().equals(end.getCity())) {
            throw new IllegalArgumentException("跑路只能在同场景内进行");
        }
    }

    /**
     * 计算跑路耗时
     *
     * @param start  起点
     * @param end    终点
     * @return 耗时(秒)
     */
    private static int calculateTime(Address start, Address end) {
        double distance = distanceTo(start,end); // 转换为公里
        return Math.max(1, (int) Math.ceil(distance / OUTDOOR_SPEED));
    }

    /**
     * 计算同场景内的距离
     *
     * @param start 另一个位置
     * @param end 另一个位置
     * @return 两点之间的距离(像素单位)
     * @throws IllegalArgumentException 如果不在同一场景
     */
    private static double distanceTo(Address start,Address end) {
        if (!start.getCity().equals(end.getCity())) {
            throw new IllegalArgumentException("Cannot calculate distance between different scenes");
        }
        int dx = start.getX() - end.getX();
        int dy = start.getY() - end.getY();
        return Math.sqrt(dx * dx + dy * dy);
    }

    /**
     * 创建反向路由
     *
     * @return 反向路由
     */
    @Override
    protected Route createReverseRoute() {
        return new RunningRoute(getEnd(), getStart());
    }

    /**
     * 获取路由描述
     *
     * @return 描述字符串
     */
    @Override
    public String getDescription() {
        return String.format("从%s跑路到%s，耗时%d秒",
                getStart(), getEnd(), getTime());
    }
}